package com.hejjon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hejjon.core.bean.TableColumn;
import com.hejjon.core.constant.TableFieldConstants;
import com.hejjon.core.domain.entity.BusinessFeature;
import com.hejjon.core.enumer.DeleteFlagEnum;
import com.hejjon.core.exception.BusinessException;
import com.hejjon.core.utils.StrUtil;
import com.hejjon.core.utils.TreeBuilder;
import com.hejjon.domain.request.BusinessFeatureCreateRequest;
import com.hejjon.domain.request.BusinessFeatureQueryRequest;
import com.hejjon.domain.request.BusinessFeatureUpdateRequest;
import com.hejjon.domain.response.BusinessFeatureCreateResponse;
import com.hejjon.domain.response.BusinessFeatureQueryResponse;
import com.hejjon.domain.response.BusinessFeatureRemoveResponse;
import com.hejjon.domain.response.BusinessFeatureUpdateResponse;
import com.hejjon.domain.vo.BusinessFeatureVO;
import com.hejjon.domain.vo.FeatureFieldVO;
import com.hejjon.mapper.BusinessFeatureMapper;
import com.hejjon.service.IBusinessFeatureService;
import com.hejjon.service.IFeatureFieldService;
import com.hejjon.service.ISqlBuilderService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static java.lang.reflect.Array.set;

/**
 * @author: cs
 * @date: 2025-05-13 20:53:13
 * @since: 1.0
 */
@Service
public class BusinessFeatureServiceImpl extends ServiceImpl<BusinessFeatureMapper, BusinessFeature>
    implements IBusinessFeatureService {

    @Resource
    private IFeatureFieldService featureFieldService;

    @Resource
    private ISqlBuilderService sqlBuilderService;

    @Resource
    private BusinessFeatureMapper businessFeatureMapper;


    @Override
    public BusinessFeatureCreateResponse create(BusinessFeatureCreateRequest request) {
        BusinessFeatureCreateResponse response = new BusinessFeatureCreateResponse();
        String name = StringUtils.replace(request.getName(), " ", "");
        boolean exist = existByNameAndLabel(name, request.getLabel());
        if (exist) {
            throw new BusinessException("业务特征名称已存在！");
        }
        BusinessFeature bf = new BusinessFeature();
        bf.setId(StrUtil.getUUID());
        bf.setName(name);
        bf.setLabel(request.getLabel());
        bf.setParentId(request.getParentId());
        bf.setType(request.getType());
        bf.setCreateTime(LocalDateTime.now());
        bf.setCreateBy("admin");
        bf.setUpdateTime(null);
        bf.setUpdateBy(null);
        bf.setDeleteFlag(DeleteFlagEnum.NO.getCode());
        boolean flag = save(bf);
        if (flag) {
            response.returnSuccess();
        } else {
            response.returnFail();
        }
        return response;
    }

    @Override
    public BusinessFeatureUpdateResponse update(BusinessFeatureUpdateRequest request) {
        BusinessFeature bf = new BusinessFeature();
        bf.setId(request.getId());
        bf.setName(request.getName());
        bf.setLabel(request.getLabel());
        boolean flag = updateById(bf);
        BusinessFeatureUpdateResponse response = new BusinessFeatureUpdateResponse();
        if (flag) {
            response.returnSuccess();
        } else {
            response.returnFail();
        }
        return response;
    }

    @Override
    public boolean existByNameAndLabel(String name, String label) {
        LambdaQueryWrapper<BusinessFeature> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BusinessFeature::getDeleteFlag,DeleteFlagEnum.NO.getCode())
                .and(w -> w.eq(StringUtils.isNotEmpty(name), BusinessFeature::getName, name)
                        .or()
                        .eq(StringUtils.isNotEmpty(label), BusinessFeature::getLabel, label));
        return exists(wrapper);
    }

    @Override
    public BusinessFeatureQueryResponse queryTreeData(BusinessFeatureQueryRequest request) {
        LambdaQueryWrapper<BusinessFeature> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BusinessFeature::getDeleteFlag,DeleteFlagEnum.NO.getCode());
        wrapper.like(StringUtils.isNotEmpty(request.getLabel()), BusinessFeature::getLabel, request.getLabel());
        List<BusinessFeature> featureList = list(wrapper);
        List<BusinessFeatureVO> voList = featureList.stream().map(bf -> {
            BusinessFeatureVO vo = new BusinessFeatureVO();
            vo.setId(bf.getId());
            vo.setName(bf.getName());
            vo.setLabel(bf.getLabel());
            vo.setParentId(bf.getParentId());
            vo.setType(bf.getType());
            return vo;
        }).collect(Collectors.toList());

        TreeBuilder<BusinessFeatureVO, String> treeBuilder = new TreeBuilder<>();
        List<BusinessFeatureVO> treeData = treeBuilder.buildTree(voList);
        BusinessFeatureQueryResponse response = new BusinessFeatureQueryResponse();
        response.setStatus(true);
        response.setMessage("ok");
        response.setDataList(treeData);
        return response;
    }

    @Override
    public List<BusinessFeatureVO> queryList(BusinessFeatureQueryRequest request) {

        return businessFeatureMapper.selectListBy(request);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessFeatureRemoveResponse removeById(String id) {
        int update = baseMapper.update(null, new LambdaUpdateWrapper<BusinessFeature>()
                .eq(BusinessFeature::getId, id).eq(BusinessFeature::getDeleteFlag, DeleteFlagEnum.NO.getCode())
                .set(BusinessFeature::getUpdateTime, LocalDateTime.now())
                .set(BusinessFeature::getUpdateBy,"admin")
                .set(BusinessFeature::getDeleteFlag, DeleteFlagEnum.YES.getCode()));
        // 删除当前业务对象的所有字段
        boolean b1 = featureFieldService.removeByFeatureId(id);
        BusinessFeatureRemoveResponse response = new BusinessFeatureRemoveResponse();
        if (update > 0) {
            response.setMessage("删除成功");
            response.setStatus(true);
        } else {
            response.setMessage("删除失败");
            response.setStatus(false);
        }

        return response;
    }

    @Override
    public String getCreateTableSql(String featureId) {

        BusinessFeature feature = getById(featureId);
        String featureName = feature.getName();
        String label = feature.getLabel();
        List<FeatureFieldVO> featureFieldVOS = featureFieldService.findByFeatureId(featureId);
        List<TableColumn> columnList = getTableColumns(featureFieldVOS);
        String createTableSql = sqlBuilderService.getCreateTableSql(featureName, label, columnList);
        System.out.println("=======================建表SQL========================");
        System.out.println(createTableSql);
        System.out.println("=====================================================");

        return createTableSql;
    }

    private List<TableColumn> getTableColumns(List<FeatureFieldVO> featureFieldVOS) {
        List<TableColumn> defaultColumnList = TableFieldConstants.getDefaultColumnList();
        List<TableColumn> columnList = new ArrayList<>(defaultColumnList);
        for (FeatureFieldVO fieldVO : featureFieldVOS) {
            TableColumn column = new TableColumn();
            column.setColumnName(fieldVO.getName());
            column.setJdbcType(fieldVO.getJdbcType());
            column.setDefaultValue(fieldVO.getDefaultValue());
            column.setComment(fieldVO.getDescription());
            column.setNotNull(false);
            column.setLength(TableFieldConstants.VARCHAR_DEFAULT_LENGTH);
            column.setPrimaryKey(false);
            columnList.add(column);
        }
        return columnList;
    }

    @Override
    public String getCreateTableSql(String featureId, String featureName, String featureLabel) {
        List<FeatureFieldVO> featureFieldVOS = featureFieldService.findByFeatureId(featureId);
        List<TableColumn> columnList = getTableColumns(featureFieldVOS);
        return sqlBuilderService.getCreateTableSql(featureName, featureLabel, columnList);
    }

}
